home *** CD-ROM | disk | FTP | other *** search
/ Mac-Source 1994 July / Mac-Source_July_1994.iso / Other Langs / MacPerl ƒ / Perl Source ƒ / MacPerl / MPPseudoFile.cp < prev    next >
Text File  |  1993-10-06  |  4KB  |  187 lines

  1. /*********************************************************************
  2. Project    :    MacPerl                -    Standalone Perl
  3. File        :    MPPseudoFile.cp    -    Pseudo files for GUSI
  4. Author    :    Matthias Neeracher
  5. Started    :    29Sep93                                Language    :    MPW C/C++
  6. Modified    :    29Sep93    MN 
  7. Last        :    29Sep93
  8. *********************************************************************/
  9.  
  10. #include "GUSI_P.h"
  11.  
  12. #include <ioctl.h>
  13. #include <sys/types.h>
  14. #include <Resources.h>
  15. #include <TextUtils.h>
  16.  
  17. extern "C" {
  18. #include "MPGlobals.h"
  19. }
  20.  
  21. #define AF_PSEUDO 18
  22.  
  23. class MPPseudoSocket;                             // That's what this file's all about
  24.  
  25. class MPPseudoSocket : public Socket    {        
  26.     friend class MPPseudoSocketDomain;    
  27.     
  28.                     MPPseudoSocket(Handle hdl);
  29.                     
  30.     virtual         ~MPPseudoSocket();
  31.     
  32.     Handle        data;
  33.     long            readEnd;
  34.     long            readPtr;
  35. public:
  36.     virtual int    read(void * buffer, int buflen);
  37.     virtual int select(Boolean * canRead, Boolean * canWrite, Boolean * exception);
  38.     virtual int    ioctl(unsigned int request, void *argp);
  39.     virtual long lseek(long offset, int whence);
  40. };    
  41.  
  42. class MPPseudoSocketDomain : public DeviceSocketDomain {
  43. public:
  44.     MPPseudoSocketDomain()    :    DeviceSocketDomain(AF_PSEUDO)    {    }
  45.     
  46.     virtual     Socket * open(const char * filename, int oflag);
  47. };
  48.  
  49. MPPseudoSocketDomain    MPPseudoSockets;
  50.  
  51. #pragma segment MPPseudo
  52.  
  53. /************************ MPPseudoSocket members ************************/
  54.  
  55. MPPseudoSocket::MPPseudoSocket(Handle hdl)
  56.     : data(hdl)
  57. {
  58.     readPtr    =    0;
  59.     readEnd    =    GetHandleSize(data);
  60. }
  61.  
  62. MPPseudoSocket::~MPPseudoSocket()
  63. {
  64.     DisposeHandle(data);
  65. }
  66.  
  67. int MPPseudoSocket::ioctl(unsigned int request, void *argp)
  68. {
  69.     switch (request)    {
  70.     case FIONREAD:
  71.         *(unsigned long *) argp    = readEnd - readPtr;
  72.         
  73.         return 0;
  74.     default:
  75.         return GUSI_error(EOPNOTSUPP);
  76.     }
  77. }
  78.  
  79. int MPPseudoSocket::read(void * buffer, int buflen)
  80. {
  81.     buflen = min(int(readEnd - readPtr), buflen);
  82.     
  83.     memcpy(buffer, (*data) + readPtr, buflen);
  84.     
  85.     readPtr += buflen;
  86.     
  87.     return buflen;
  88. }
  89.  
  90. int MPPseudoSocket::select(Boolean * canRead, Boolean * canWrite, Boolean * exception)
  91. {
  92.     int        goodies     =     0;
  93.         
  94.     if (canRead)
  95.         if (*canRead = readEnd > readPtr)
  96.             ++goodies;
  97.     
  98.     if (canWrite)
  99.         *canWrite = false;
  100.     
  101.     if (exception)
  102.         *exception = false;
  103.     
  104.     return goodies;
  105. }
  106.  
  107. long MPPseudoSocket::lseek(long offset, int whence)
  108. {
  109.     long    nuReadPtr;
  110.     
  111.     switch (whence) {
  112.     case SEEK_END:
  113.         nuReadPtr = readEnd + offset;
  114.         break;
  115.     case SEEK_CUR:
  116.         nuReadPtr = readPtr + offset;
  117.         break;
  118.     case SEEK_SET:
  119.         nuReadPtr = offset;
  120.         break;
  121.     default:
  122.         return GUSI_error(EINVAL);
  123.     }
  124.     
  125.     if (nuReadPtr > readEnd)
  126.         return GUSI_error(ESPIPE);
  127.     if (nuReadPtr < 0)
  128.         return GUSI_error(EINVAL);
  129.     
  130.     return readPtr = nuReadPtr;
  131. }
  132.  
  133. /********************* MPPseudoSocketDomain member **********************/
  134.  
  135. #pragma force_active on
  136.  
  137. Socket * MPPseudoSocketDomain::open(const char * filename, int flags)
  138. {
  139.     Socket *            sock = nil;
  140.     char                 title[256];
  141.     Boolean            nudoc = false;
  142.     
  143.     strncpy(title, filename, 6);
  144.     title[6] = 0;
  145.     
  146.     if (equalstring(title, (char *) "Pseudo", false, true)) {
  147.         switch (filename[6]) {
  148.         case ':':
  149.             ++filename;
  150.         case 0:
  151.             filename += 6;
  152.             break;
  153.         default:
  154.             goto nope;
  155.         }
  156.  
  157.         if (flags & ~O_BINARY)
  158.             return (Socket *) GUSI_error_nil(EPERM);
  159.             
  160.         if (!*filename) {
  161.             sock = new MPPseudoSocket(gPseudoFile);
  162.             
  163.             gPseudoFile = nil;
  164.         } else {
  165.             short        res    =    CurResFile();
  166.             Handle    data;
  167.             
  168.             UseResFile(gScriptFile);
  169.             
  170.             data = getnamedresource('TEXT', (char *) filename);
  171.             
  172.             if (data) {
  173.                 DetachResource(data);
  174.                 
  175.                 sock = new MPPseudoSocket(data); 
  176.             }
  177.             
  178.             UseResFile(res);
  179.         }
  180.  
  181.         return sock;
  182.     } 
  183.  
  184. nope:
  185.     return (Socket *) TryNextDevice;
  186. }
  187.